<?php
// +----------------------------------------------------------------------
// | QSCMS
// +----------------------------------------------------------------------
// | Copyright (c)  2025 https://www.qqss.net All rights reserved.
// +----------------------------------------------------------------------
// | Licensed QSCMS is not free software, commercial use must purchase official license from official website to avoid unnecessary legal disputes.
// +----------------------------------------------------------------------
// | Author: Contract 990504246@qq.com
// +----------------------------------------------------------------------

namespace app\common\taglib;

use think\template\TagLib;

/**
 * 通用数据标签库
 */
class Cms extends TagLib
{
    /**
     * 标签库名称
     */
    protected $tagLib = 'cms';

    /**
     * 定义标签列表
     */
    protected $tags = [
        'goods'      => ['attr' => 'limit,cate_id,type,order,image', 'close' => 1],
        'categories' => ['attr' => 'limit,pid', 'close' => 1],
        'count'      => ['attr' => 'type,category', 'close' => 0],
        'hooks'      => ['attr' => 'name,data', 'close' => 0],
        'plugin'     => ['attr' => 'name,method,data', 'close' => 0],
    ];

    /**
     * 递归获取某分类的所有子孙 ID
     * @param int $rootId 起始分类 id
     * @return int[]
     */
    function getSubIds(int $rootId): array
    {
        $ids = [];

        // 先拿直接子级
        $children = \think\facade\Db::name('goods_category')
            ->where('pid', $rootId)
            ->column('id');

        foreach ($children as $id) {
            $ids[] = $id;
            // 递归拿孙级、曾孙级……
            $ids = array_merge($ids, $this->getSubIds($id));
        }

        return $ids;
    }

    /**
     * 商品列表标签
     * {cms:goods limit="10" cate_id="1" type="recommend" image="1"}
     */
    public function tagGoods($tag, $content)
    {
        $limit   = $tag['limit'] ?? 10;
        $cate_id = $tag['cate_id'] ?? 0;
        $image   = $tag['image'] ?? 0;
        // 是否包含下级
        $has_children = $tag['has_children'] ?? 0;

        $parse = '<?php ';
        $parse .= '$__goods_list__ = \\app\\common\\model\\Goods::where("status", 1)';

        if ($cate_id) {
            $cate_var = $this->autoBuildVar($cate_id);
            if ($has_children) {
                $subIds    = $this->getSubIds(intval($cate_id));
                $subIdsStr = implode(',', $subIds);
                $parse .= '->where("cate_id", "in", ' . $subIdsStr . ' )';
            } else {
                $parse .= '->where("cate_id", ' . $cate_var . ')';
            }
            echo $parse;
        }

        if ($image) {
            $parse .= '->where("slider_image", "!=", "[]")';
        }
        $parse .= '->order("sort desc, id desc")';
        $parse .= '->limit(' . $limit . ')';
        $parse .= '->select(); ';
        $parse .= 'if($__goods_list__): foreach($__goods_list__ as $key => $goods): ';
        // 为每个商品添加自定义URL
        $parse .= '$goods["url"] = _url_("goods.detail", ["id" => $goods->id]); ';
        $parse .= '?>';
        $parse .= $content;
        $parse .= '<?php endforeach; endif; ?>';
        return $parse;
    }

    /**
     * 分类列表标签
     * {cms:categories limit="10" pid="0"}
     */
    public function tagCategories($tag, $content)
    {
        $limit  = $tag['limit'] ?? 20;
        $parent = $tag['parent'] ?? 0;

        $parse      = '<?php ';
        $parse .= '$__categories_list__ = \\app\\common\\model\\GoodsCategory::where("status", 1)';
        $parent_var = $this->autoBuildVar($parent);
        $parse .= '->where("pid", ' . $parent_var . ')';
        $parse .= '->order("sort", "desc")';
        $parse .= '->limit(' . $limit . ')';
        $parse .= '->select(); ';
        $parse .= 'if($__categories_list__): foreach($__categories_list__ as $key => $category): ';
        // 为每个分类添加自定义URL
        $parse .= '$category["url"] = _url_("goods.category", ["pinyin" => $category->pinyin]); ';
        $parse .= '?>';
        $parse .= $content;
        $parse .= '<?php endforeach; endif; ?>';

        return $parse;
    }

    /**
     * 统计数量标签
     * {data:count type="goods" category="1"}
     */
    public function tagCount($tag, $content)
    {
        $type     = isset($tag['type']) ? trim($tag['type'], '"\'') : 'goods';
        $category = isset($tag['category']) ? intval($tag['category']) : 0;

        $parse = '<?php ';

        switch ($type) {
            case 'goods':
                $parse .= '$__count_result__ = \\app\\common\\model\\Goods::where("status", 1)';
                if ($category) {
                    $category_var = $this->autoBuildVar($category);
                    $parse .= '->where("cate_id", ' . $category_var . ')';
                }
                $parse .= '->count();';
                break;
            case 'categories':
                $parse .= '$__count_result__ = \\app\\common\\model\\GoodsCategory::where("status", 1)->count();';
                break;
            default:
                $parse .= '$__count_result__ = 0;';
                break;
        }

        $parse .= ' echo $__count_result__; ?>';

        return $parse;
    }


    /**
     * Hook标签
     * {cms:hook name="header_scripts" data="$data" /}
     */
    public function tagHooks($tag, $content)
    {
        $name = isset($tag['name']) ? trim($tag['name'], '"\'') : '';
        $data = isset($tag['data']) ? $tag['data'] : 'null';
        if (empty($name)) {
            return '';
        }

        $parse = '<?php ';
        $parse .= 'echo hook("' . $name . '", ' . $data . '); ';
        $parse .= '?>';

        return $parse;
    }

    /**
     * 插件标签
     * {cms:plugin name="background_image" method="render" data="$data" /}
     */
    public function tagPlugin($tag, $content)
    {
        $name   = isset($tag['name']) ? trim($tag['name'], '"\'') : '';
        $method = isset($tag['method']) ? trim($tag['method'], '"\'') : 'render';
        $data   = isset($tag['data']) ? $tag['data'] : 'null';

        if (empty($name)) {
            return '';
        }

        $parse = '<?php ';
        $parse .= '$__plugin_manager__ = \\app\\common\\plugin\\PluginManager::getInstance(); ';
        $parse .= '$__plugin_instance__ = $__plugin_manager__->getPluginInstance("' . $name . '"); ';
        $parse .= 'if ($__plugin_instance__ && is_plugin_enabled("' . $name . '") && method_exists($__plugin_instance__, "' . $method . '")) { ';
        $parse .= '    echo $__plugin_instance__->' . $method . '(' . $data . '); ';
        $parse .= '} ';
        $parse .= '?>';

        return $parse;
    }
}
